﻿using System;
using System.Runtime;
using System.Security;

namespace SynergyLib.SMath
{
    public static class Trig
    {

        public const double Radian = 360 / (2 * System.Math.PI);

        public const double TwoPI = (2 * System.Math.PI);

        /// <summary>
        /// Returns an angle in degrees' radian equivalent.
        /// </summary>
        /// <param name="degrees"></param>
        /// <returns></returns>
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public static double DegsToRads(double degrees)
        {
            return degrees / Radian;
        }

        /// <summary>
        /// Returns an angle in radians' Degree equivalent.
        /// </summary>
        /// <param name="radians"></param>
        /// <returns></returns>
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public static double RadsToDegs(double radians)
        {
            return radians * Radian;
        }

        /// <summary>
        /// Find delta of an angle with respect to another angle.
        /// </summary>
        /// <param name="theta1"></param>
        /// <param name="theta2"></param>
        /// <returns></returns>
        [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
        public static double CalculateDelta(double theta1, double theta2)
        {
            if (theta1 < 0) theta1 += 360;
            if (theta2 < 0) theta2 += 360;
            double theta1DeltaFromZero = theta1 < 180 ? theta1 : theta1 - 360;
            double theta2DeltaFromZero = theta2 < 180 ? theta2 : theta2 - 360;

            double delta = 0;

            if (System.Math.Sign(theta1DeltaFromZero) == System.Math.Sign(theta2DeltaFromZero))
            {
                delta = theta1DeltaFromZero - theta2DeltaFromZero;
            }
            else if (theta1DeltaFromZero == 0)
            {
                delta = -theta2DeltaFromZero;
            }
            else if (theta2DeltaFromZero == 0)
            {
                delta = theta1DeltaFromZero;
            }
            else
            {
                delta = System.Math.Abs(theta1DeltaFromZero) + System.Math.Abs(theta2DeltaFromZero);

                Int32 sign = 1;

                if (theta2DeltaFromZero > theta1DeltaFromZero)
                    sign = -1;

                if (delta > 180)
                {
                    delta -= 360;
                }

                delta *= sign;
            }

            return delta;
        }

        public static float AngleToCutoffFrequency(double angle, int sampleRate)
        {
            return (float)(2 * System.Math.Sin(System.Math.PI * System.Math.Abs(angle) / sampleRate));
        }
    }
}
